package com.example.ws.handler.chess;

public class BoxChess {

    public int[][] chess;

    public static final int CHESS_TYPE_NONE = 0;
    public static final int CHESS_TYPE_WHITE = 1;
    public static final int CHESS_TYPE_BLACK = 2;

    public static final int CHESS_ROLE_NONE = 0;
    public static final int CHESS_ROLE_A = 1;
    public static final int CHESS_ROLE_B = 2;

    // 上个落点位置
    public Pos lastDownPos;
    // A上次落点位置
    public Pos ALastDownPos;
    // B上次落点位置
    public Pos BLastDownPos;

    // 上次落点角色
    public int lastChessRole;

    public int win = CHESS_ROLE_NONE;

    public BoxChess(int col, int row) {

        chess = new int[row][col];

    }

    // 落点
    public int down(int chessRole, Pos pos) {
        int chessType = getChessRoleChessType(chessRole);
        if (win != CHESS_ROLE_NONE) {
            return CHESS_ROLE_NONE;
        }
        if (chessType != CHESS_TYPE_WHITE && chessType != CHESS_TYPE_BLACK)
            throw new RuntimeException("Invalid chess type => " + chessType);
        if (chessRole != CHESS_ROLE_A && chessRole != CHESS_ROLE_B)
            throw new RuntimeException("Invalid chess role => " + chessRole);
        chess[pos.x()][pos.y()] = chessType;
        if (chessRole == CHESS_ROLE_A) {
            ALastDownPos = pos;
        }
        if (chessRole == CHESS_ROLE_B) {
            BLastDownPos = pos;
        }
        lastDownPos = pos;
        lastChessRole = chessRole;
        // 判断输赢
        win = win();

        // 把原来树的不存在分支去掉
        // 更新得分树
        return win;
    }

    public int nextChessRole() {
        if (lastChessRole == CHESS_ROLE_A) return CHESS_ROLE_B;
        if (lastChessRole == CHESS_ROLE_B) return CHESS_ROLE_A;
        throw new RuntimeException("Invalid last chess role => " + lastChessRole);
    }

    // ---------------------------------- pri ------------------------------------------

    private int getChessRoleChessType(int chessRole) {
        if (chessRole == CHESS_ROLE_A) return CHESS_TYPE_WHITE;
        if (chessRole == CHESS_ROLE_B) return CHESS_TYPE_BLACK;
        throw new RuntimeException("Invalid chess role => " + chessRole);
    }

    // 判断谁胜利了
    private int win() {
        int lastChessType = getChessRoleChessType(lastChessRole);
        int left = statisticLeft(lastChessType);
        int right = statisticRight(lastChessType);
        if (left + right + 1 >= 5) {
            return lastChessRole;
        }
        int up = statisticUp(lastChessType);
        int down = statisticDown(lastChessType);
        if (up + down + 1 >= 5) {
            return lastChessRole;
        }
        int leftUp = statisticLeftUp(lastChessType);
        int rightDown = statisticRightDown(lastChessType);
        if (leftUp + rightDown + 1 >= 5) {
            return lastChessRole;
        }
        int leftDown = statisticLeftDown(lastChessType);
        int rightUp = statisticRightUp(lastChessType);
        if (leftDown + rightUp + 1 >= 5) {
            return lastChessRole;
        }
        return CHESS_ROLE_NONE;
    }

    // 统计左边对应类型棋子数
    private int statisticLeft(int chessType) {
        int count = 0;
        for (int i = lastDownPos.x() - 1; i >= 0; i--) {
            if (chess[i][lastDownPos.y()] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    private int statisticRight(int chessType) {
        int count = 0;
        for (int i = lastDownPos.x() + 1; i < chess[0].length; i++) {
            if (chess[i][lastDownPos.y()] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    private int statisticUp(int chessType) {
        int count = 0;
        for (int i = lastDownPos.y() - 1; i >= 0; i--) {
            if (chess[lastDownPos.x()][i] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    private int statisticDown(int chessType) {
        int count = 0;
        for (int i = lastDownPos.y() + 1; i < chess.length; i++) {
            if (chess[lastDownPos.x()][i] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }

    private int statisticLeftUp(int chessType) {
        int count = 0;
        for (int x = lastDownPos.x() - 1, y = lastDownPos.y() - 1; x >= 0 && y >= 0; x--, y--) {
            if (chess[x][y] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }
    private int statisticRightDown(int chessType) {
        int count = 0;
        for (int x = lastDownPos.x() + 1, y = lastDownPos.y() + 1; x < chess[0].length && y < chess.length; x++, y++) {
            if (chess[x][y] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }
    private int statisticRightUp(int chessType) {
        int count = 0;
        for (int x = lastDownPos.x() + 1, y = lastDownPos.y() - 1; x < chess[0].length && y >= 0; x++, y--) {
            if (chess[x][y] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }
    private int statisticLeftDown(int chessType) {
        int count = 0;
        for (int x = lastDownPos.x() - 1, y = lastDownPos.y() + 1; x >= 0 && y < chess.length; x--, y++) {
            if (chess[x][y] == chessType) {
                count++;
            } else {
                break;
            }
        }
        return count;
    }
}
